﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace M3G {
    public static class MySystemExtensions {
        public static float Clamp (this float val, float min, float max) {
            if (val.CompareTo (min) < 0) return min;
            else if (val.CompareTo (max) > 0) return max;
            else return val;
        }

        public static int LastIndexOf<T> (this T[] array, Predicate<T> match) {
            var found = -1;
            for (var i = 0; i < array.Length; i++) {
                if (match (array[i]))
                    found = i;
            }
            return found;
        }

        public static int IndexOf<T> (this List<T> array, Predicate<T> match) {
            var found = -1;
            for (var i = 0; i < array.Count; i++) {
                if (match (array[i]))
                    found = i;
            }
            return found;
        }

        public static bool Exists<T> (this T[] array, Predicate<T> match) {
            for (var i = 0; i < array.Length; i++) {
                if (match (array[i]))
                    return true;
            }
            return false;
        }

        public static float[] Normalize (this float[] array) {
            if (array.Length != 3) {
                throw new InvalidOperationException ("Array length must be 3 or 4, len=" + array.Length);
            }
            var length = array.Norm ();
            for (var i=0; i < 3; i++) {
                array[i] /= length;
            }
            return array;
        }

        public static float Norm (this float[] array) {
            if (array.Length != 3) {
                throw new InvalidOperationException ("Array length must be 3 or 4, len=" + array.Length);
            }
            return (float)Math.Sqrt (array.Sum (x => x * x));
        }

        public static float[] DividedByW (this float[] array) {
            if (array.Length != 4) {
                throw new InvalidOperationException ("Array lenght must be 4, len=" + array.Length);
            }
            for (var i=0; i < 4; i++) {
                array[i] /= array[3];
            }
            return array;
        }

        public static float[] LookTo (this float[] pos1, float[] pos2) {
            if (pos1.Length != 3 || pos2.Length != 3) {
                throw new InvalidOperationException ("Array length must be 3 or 4, len=" + pos1.Length + ",len=" + pos2.Length);
            }
            var dir = new float[]{pos2[0] - pos1[0],
                                  pos2[1] - pos1[1],
                                  pos2[2] - pos1[2]};
            return dir.Normalize ();
        }

    }
}
